package com.itheima.aspect;

import com.itheima.anno.LogAnno;
import com.itheima.mapper.OperateLogMapper;
import com.itheima.pojo.OperateLog;
import com.itheima.util.UserHolder;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Date;

@Component
@Aspect //切面
public class LogAspect {

    @Autowired
    private HttpServletRequest request;

    @Autowired
    private OperateLogMapper operateLogMapper;

    //自定义注解
    @Pointcut("@annotation(com.itheima.anno.LogAnno)")
    public void pt() {

    }

    //环绕通知
    @Around("pt()")
    public Object logAround(ProceedingJoinPoint pjp) {
        OperateLog operateLog = new OperateLog();

        //操作时间
        operateLog.setOperateTime(LocalDateTime.now());
        //全类名
        operateLog.setClassName(pjp.getTarget().getClass().getName());
        //请求参数
        operateLog.setMethodParams(Arrays.toString(pjp.getArgs()));

        MethodSignature ms = (MethodSignature) pjp.getSignature();
        Method method = ms.getMethod();

        //方法名
        operateLog.setMethodName(method.getName());
        //方法作用(从LogAnno注解属性中获取)
        operateLog.setMethodDesc(method.getAnnotation(LogAnno.class).methodDesc());

        operateLog.setOperateUser(UserHolder.get());

        Object obj = null;
        long start = new Date().getTime();
        try {
            obj = pjp.proceed();

            //方法的执行结果
            operateLog.setReturnValue(obj.toString());
            return obj;
        } catch (Throwable e) {
            throw  new RuntimeException(e);
        }finally {
            long end = new Date().getTime();
            //方法执行时长
            operateLog.setCostTime(end-start);
            //保存日志
            operateLogMapper.insert(operateLog);
        }


    }


}